package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.atguigu.tingshu.vo.album.TrackListVo;
import com.atguigu.tingshu.vo.album.TrackMediaInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private VodConstantProperties vodConstantProperties;

	@Autowired
	private TrackStatMapper trackStatMapper;

	@Autowired
	private AlbumInfoMapper albumInfoMapper;


	@Autowired
	private VodService vodService;

	@Override
	public Map<String, Object> uploadTrack(MultipartFile file) {

		//  声音上传临时目录：
		String tempPath = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);
		VodUploadClient vodUploadClient = new VodUploadClient(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());
		//  创建上传声音客户端
		VodUploadClient client = new VodUploadClient(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());

		//  构建上传请求对象
		VodUploadRequest request = new VodUploadRequest();
		//  设置视频本地地址
		request.setMediaFilePath(tempPath);
		//  指定任务流
		request.setProcedure(vodConstantProperties.getProcedure());
		//  调用上传方法
        VodUploadResponse response = null;
        try {
            response = client.upload(vodConstantProperties.getRegion(), request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //  创建map 对象
		HashMap<String, Object> map = new HashMap<>();
		map.put("mediaFileId",response.getFileId());
		map.put("mediaUrl",response.getMediaUrl());
		//  返回map 数据
		return map;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveTrackInfo(TrackInfoVo trackInfoVo) {

		TrackInfo trackInfo = new TrackInfo();
		BeanUtils.copyProperties(trackInfoVo,trackInfo);

		Long userId = AuthContextHolder.getUserId();
		if (null == userId){
			throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
		}
		trackInfo.setUserId(userId);
		//声音的顺序，查询最后一条
		TrackInfo dbTrackInfo = this.lambdaQuery()
				.eq(TrackInfo::getAlbumId, trackInfoVo.getAlbumId())
				.orderByDesc(TrackInfo::getId)
				.last(" limit 1")
				.one();
		int orderNum = 1;
		//不为空说明专辑下已经有声音，所以数量加1
		if (null != dbTrackInfo) {
			orderNum = dbTrackInfo.getOrderNum() + 1;
		}
		//设置数量
		trackInfo.setOrderNum(orderNum);

		//编写方法保存 media_file_id ---> 调用api
		TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
		trackInfo.setMediaSize(trackMediaInfoVo.getSize());
		trackInfo.setMediaType(trackMediaInfoVo.getType());
		trackInfo.setMediaUrl(trackMediaInfoVo.getMediakUrl());
		trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
		//设置状态审核通过
		trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
		this.trackInfoMapper.insert(trackInfo);

		//保存声音统计 播放量、收藏量、点赞数、评论数
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COLLECT);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PRAISE);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COMMENT);

		//更新专辑对应的总数
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
		albumInfoMapper.updateById(albumInfo);

	}


	/**
	 * 查看声音列表
	 * @param trackListVoPage
	 * @param trackInfoQuery
	 * @return
	 */
	@Override
	public IPage<TrackListVo> findUserTrackPage(Page<TrackListVo> trackListVoPage, TrackInfoQuery trackInfoQuery) {
		//获取用户id
		Long userId = AuthContextHolder.getUserId();
		if (null == userId){
			throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
		}
		trackInfoQuery.setUserId(userId);
		//调用mapper层查询
		return trackInfoMapper.selectUserTrackPage(trackListVoPage,trackInfoQuery);
	}

	private void saveTrackStat(Long id, String statType) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(id);
		trackStat.setStatType(statType);
		trackStatMapper.insert(trackStat);
	}


	/**
	 * 删除声音
	 * @param trackId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeTrackInfoById(Long trackId) {
		//查询声音对象，后续做删除
		TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
		//删除trackInfo
		trackInfoMapper.deleteById(trackId);
		//更新专辑包含的声音总数
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		if (albumInfo != null){
			albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() == null ? 0 : albumInfo.getIncludeTrackCount() -1);
			albumInfoMapper.updateById(albumInfo);
		}
		//删除声音统计
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>()
				.eq(TrackStat::getTrackId,trackId));
		//删除流媒体数据
		vodService.removeTrack(trackInfo.getMediaFileId());
	}

	/**
	 * 根据声音id获取回显数据
	 * @param trackId
	 * @return
	 */
	@Override
	public TrackInfo getTrackInfoById(Long trackId) {
		TrackInfo trackInfo = this.getById(trackId);
		return trackInfo;
	}

	/**
	 * 修改声音
	 * @param trackId
	 * @param trackInfoVo
	 */
	@Override
	public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
		//获取原来的声音对象
		TrackInfo trackInfo = this.getById(trackId);
		//获取原始的media
		String mediaFileId = trackInfo.getMediaFileId();
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		if (!trackInfoVo.getMediaFileId().equals(trackInfoVo.getMediaFileId())){
			//如果不相等说明声音被修改过，根据声音id获取现在的属性信息
			TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
			if (trackMediaInfo == null){
				throw new GuiguException(ResultCodeEnum.VOD_FILE_ID_ERROR);
			}
			//更新声音信息
			trackInfo.setMediaSize(trackMediaInfo.getSize());
			trackInfo.setMediaType(trackMediaInfo.getType());
			trackInfo.setMediaUrl(trackMediaInfo.getMediakUrl());
			trackInfo.setMediaDuration(trackMediaInfo.getDuration());
		}
		//修改声音
		this.updateById(trackInfo);
	}
}
